/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package orgarqsindex;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 *
 * @author Fernando Molon Toigo e Dyoni Bertuol
 */
public class HashIndexFileGenerator {

    private File sourceFile;
    private File targetFile;
    private int rowSize;
    private int fieldBeginIndex;
    private int fieldSize;
    private int indexRowSize;
    private long blockSize;

    public HashIndexFileGenerator(File sourceFile, File targetFile, int rowSize, int fieldBeginIndex, int fieldSize) {
        this.sourceFile = sourceFile;
        this.targetFile = targetFile;
        this.rowSize = rowSize;
        this.fieldBeginIndex = fieldBeginIndex;
        this.fieldSize = fieldSize;
        this.indexRowSize = String.valueOf(sourceFile.length() / rowSize).length() + 2;
    }
    
    public void generate() throws FileNotFoundException, IOException{
        if (targetFile.exists()){
            targetFile.delete();
        }
        
        RandomAccessFile sraf = new RandomAccessFile(sourceFile, "r");
        RandomAccessFile traf = new RandomAccessFile(targetFile, "rw");
        
        byte[] buffer = new byte[fieldSize];
        
        blockSize = findHigher(sraf);
        int blocksAmount = (int)Math.pow(10, fieldSize);
        long[] blocksCurrentAmount = new long[blocksAmount];
        
        createBlankFile(traf, getBlockSize() * blocksAmount * indexRowSize);
        
        sraf.seek(0);
        
        for (long i = 0; i < sourceFile.length(); i += rowSize){
            sraf.seek(i + fieldBeginIndex);
            sraf.read(buffer);

            int value = Integer.valueOf(new String(buffer, "ISO-8859-1"));
            
            traf.seek(indexRowSize * (getBlockSize() * value + blocksCurrentAmount[value]));
            
            traf.writeBytes(String.format("%0" + String.valueOf(sourceFile.length() / rowSize).length() + "d", i / rowSize) + "\r\n");
            
            blocksCurrentAmount[value]++;
        }
        
        sraf.close();
        traf.close();
    }
        
    private long findHigher(RandomAccessFile sraf) throws IOException {
        
        byte[] buffer = new byte[fieldSize];
        
        long[] amountPerValue = new long[(int)Math.pow(10, fieldSize)];
        
        for (long i = 0; i < sourceFile.length(); i += rowSize){
        
            sraf.seek(i + fieldBeginIndex);
            sraf.read(buffer);
            
            int value = Integer.valueOf(new String(buffer, "ISO-8859-1"));
            
            amountPerValue[value]++;
        }
        
        long highest = 0;
        for (long amount : amountPerValue){
            if (amount > highest)
                highest = amount;
        }
        
        return highest;
    }
    
    private void createBlankFile(RandomAccessFile traf, long fileSize) throws IOException{
        traf.seek(0);
        
        byte[] buffer = new byte[(int)fileSize];
        
        traf.write(buffer);
    }

    public long getBlockSize() {
        return blockSize;
    }
}
